package com.bitcs.accesscontrol.log;

import com.bitcs.accesscontrol.dao.entity.AccessLogPO;
import com.bitcs.accesscontrol.service.AccessService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.concurrent.Callable;

/**
 * @author gc
 */
public class SaveLogTask implements Callable<String> {

    ProceedingJoinPoint joinPoint;
    HttpServletRequest httpServletRequest;
    AccessService accessService;

    public SaveLogTask(ProceedingJoinPoint proceedingJoinPoint, HttpServletRequest httpServletRequest, AccessService accessService) {
        this.joinPoint = proceedingJoinPoint;
        this.httpServletRequest = httpServletRequest;
        this.accessService = accessService;
    }


    /**
     * 保存到日志
     *
     * @param proceedingJoinPoint
     */
    private String saveLog(ProceedingJoinPoint proceedingJoinPoint, HttpServletRequest httpServletRequest) {
        AccessLogPO accessLogPO = new AccessLogPO();
        String res = null;
        try {
            long transferTime = System.currentTimeMillis();
            String remoteAddr = httpServletRequest.getRemoteAddr();
            String methodName = proceedingJoinPoint.getSignature().getName();
            MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
            Method method = methodSignature.getMethod();
            String operationName = method.getAnnotation(AccessLog.class).operationName();
            int remotePort = httpServletRequest.getRemotePort();
            StringBuilder stringBuilder = new StringBuilder();
            Object[] paramsArray = proceedingJoinPoint.getArgs();
            for (int i = 0; i < paramsArray.length; i++) {
                stringBuilder.append(paramsArray[i] + ",");
            }
            String params = stringBuilder.toString();
            accessLogPO.setMethodName(methodName);
            accessLogPO.setRemotePort(remotePort);
            accessLogPO.setRemoteAddr(remoteAddr);
            accessLogPO.setTransferTime(new Date(transferTime));
            accessLogPO.setOperationName(operationName);
            accessLogPO.setParams(params);
            res = proceedingJoinPoint.proceed().toString();
            accessLogPO.setExceptionDetail(AccessLogPO.Const.STRING_NO_EXCEPTION);
        } catch (Throwable e) {
            e.printStackTrace();
            accessLogPO.setExceptionDetail(e.toString());
        }
        accessService.insertAccessLog(accessLogPO);
        return res;
    }

    @Override
    public String call() throws Exception {
        return saveLog(joinPoint, httpServletRequest);
    }
}
